package org.oslims.server.dao.hbm;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.oslims.domain.Analysis;
import org.oslims.domain.SampleType;
import org.oslims.server.dao.AnalysisDao;

public class HbmAnalysisDao extends HbmGenericDao<Analysis, Long> implements AnalysisDao {

	@SuppressWarnings("unchecked")
	@Override
	public List<Analysis> findAllWithParametersAndDepartment() {
		Query q = this.getSession().createQuery("select distinct a from Analysis a left join fetch a.determinedParameters order by a.name");
		return q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Analysis> findAllWithParametersAndDepartment(int start, int length, String sortBy, Boolean desc) {
		String sortDirection = "asc";

		if (desc)
			sortDirection = "desc";

		Query q = this.getSession().createQuery("select distinct a from Analysis a left join fetch a.determinedParameters order by a." + sortBy + " " + sortDirection);
		q.setFirstResult(start);
		q.setMaxResults(length);

		return q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Analysis> findAllForSampleTypes(List<SampleType> sampleTypes) {

		String whereClause = "";

		for (SampleType st : sampleTypes) {

			whereClause += " a.id in (";

			// Abort if one selected sample type has no analysis defined
			if (st.getPossibleAnalysis().size() == 0) {
				whereClause = "";
				break;
			}

			for (Analysis a : st.getPossibleAnalysis()) {
				whereClause += a.getId() + ", ";
			}

			whereClause = whereClause.substring(0, whereClause.length() - 2);

			whereClause += ") and";
		}

		if (!whereClause.isEmpty()) {
			whereClause = whereClause.substring(0, whereClause.length() - 4);
		} else {
			return new ArrayList<Analysis>();
		}

		Query q = this.getSession().createQuery("select distinct a from Analysis a where " + whereClause + " order by a.doneIn.abbreviation, a.name");

		return q.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Analysis> findAllByStateWithParametersAndDepartment(String state) {
		Query q = this.getSession().createQuery(
				"select distinct a from Analysis a left join fetch a.determinedParameters join a.analysisResults ar where ar.state = :state order by a.name");
		q.setString("state", state);

		return q.list();
	}
}
